﻿/**
* CRL
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CRL.Core.Remoting
{
    public class ServerCreater
    {
        public static ServerCreater Instance;
        public ServerCreater()
        {
            Instance = this;
        }
        bool _UseCoreInjection = false;
        public ServerCreater UseCoreInjection()
        {
            _UseCoreInjection = true;
            return this;
        }
        
        public static string __HeadTokenName = "token";
        //public void SetHeadTokenName(string name)
        //{
        //    __HeadTokenName = name;
        //}

        ServerType currentServerType;
        Dictionary<ServerType, AbsServer> servers = new Dictionary<ServerType, AbsServer>();
        public void SetServer(AbsServer server, ServerType serverType)
        {
            servers.Add(serverType,server);
            currentServerType = serverType;
            server.SetServerCreater(this);
        }
        public AbsServer GetServer(ServerType serverType)
        {
            servers.TryGetValue(serverType, out var server);
            return server;
        }
        #region 注册服务
        static Dictionary<string, serviceInfo> serviceHandle = new Dictionary<string, serviceInfo>(StringComparer.OrdinalIgnoreCase);
        /// <summary>
        /// 指定类型注册
        /// </summary>
        /// <typeparam name="IService"></typeparam>
        /// <typeparam name="Service"></typeparam>
        public void Register<IService, Service>() where Service : AbsService, IService where IService : class
        {
            Register(typeof(IService), typeof(Service));
        }
        internal void Register(Type interfaceType, Type serviceType, bool initObjCtor = true)
        {
            var server = GetServer(currentServerType);
            var __DefaultApiPrefix = server.__DefaultApiPrefix;
            var info = serviceInfo.GetServiceInfo(__DefaultApiPrefix, serviceType, initObjCtor);
            info.InterfaceType = interfaceType;
            var serviceKey = $"{currentServerType}.{info.ServiceAttribute.ApiPrefix}.{(currentServerType == ServerType.DynamicWebApi ? interfaceType : serviceType).Name}";
            Console.WriteLine($"ApiService: {serviceKey}");
            serviceHandle.Add(serviceKey, info);
        }
        public bool CheckServerExists(string serviceKey, out serviceInfo serviceInfo)
        {
            return serviceHandle.TryGetValue(serviceKey, out serviceInfo);
        }
        public ServerCreater Register(Type interfaceType, Type serviceType)
        {
            Register(interfaceType, serviceType);
            return this;
        }
        /// <summary>
        /// 按类型所在程序集注册所有
        /// </summary>
        /// <param name="assemblies"></param>
        /// <returns></returns>
        public ServerCreater RegisterAll(params Assembly[] assemblies)
        {
            foreach (var assembyle in assemblies)
            {
                var types = assembyle.GetTypes();
                foreach (var type in types)
                {
                    if (type.IsSubclassOf(typeof(AbsService)) && !type.IsAbstract)
                    {
                        var implementedInterface = GetImplementedInterface(type);
                        if (implementedInterface == null && currentServerType == ServerType.DynamicWebApi)
                        {
                            Console.WriteLine($"DynamicWebApi {type} 未实现接口，跳过");
                            continue;
                        }
                        Register(implementedInterface, type, _UseCoreInjection ? false : true);
                    }
                }
            }
            return this;
        }

        #endregion
        static bool MyInterfaceFilter(Type typeObj, Object criteriaObj)
        {
            var baseClassType = (Type)criteriaObj;
            var interfaces_array = baseClassType.GetInterfaces();
            for (int i = 0; i < interfaces_array.Length; i++)
            {
                if (typeObj.ToString() == interfaces_array[i].ToString())
                    return false;
            }
            return true;
        }
        public static Type GetImplementedInterface(Type type)
        {
            var theFilter = new System.Reflection.TypeFilter(MyInterfaceFilter);
            var implementedInterface = type.FindInterfaces(theFilter, type.BaseType).FirstOrDefault();
            return implementedInterface;
        }
        public void Start()
        {
            var Server = GetServer(currentServerType);
            Server.Start();
        }
        public void Dispose()
        {
            var Server = GetServer(currentServerType);
            Server.Dispose();
        }
    }

    public delegate bool TokenCheckHandler(MessageBase req, out object user, out string error);
}
